package cn.schoolwow.workflow.module.task.action.flow.common;

import cn.schoolwow.quickdao.domain.DAO;
import cn.schoolwow.quickdao.domain.database.dql.condition.Condition;
import cn.schoolwow.quickdao.domain.transaction.Transaction;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.util.domain.query.instanceList.QueryInstanceList;
import cn.schoolwow.workflow.domain.deploy.DeployApprovalType;
import cn.schoolwow.workflow.domain.task.CompleteTaskRequest;
import cn.schoolwow.workflow.entity.WorkFlowInstance;
import cn.schoolwow.workflow.entity.WorkFlowNode;
import cn.schoolwow.workflow.entity.WorkFlowTask;
import cn.schoolwow.workflow.module.task.action.domain.CompleteTaskOption;

import java.util.List;

public class SetNodeAssignerFinishedOptionCommonFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        WorkFlowNode workFlowNode = flowContext.checkInstanceData(WorkFlowNode.class);
        CompleteTaskOption completeTaskOption = flowContext.checkInstanceData(CompleteTaskOption.class);

        if(null==workFlowNode.getApprovalType()){
            completeTaskOption.setNextNode = true;
        }else{
            //判断多人审批类型
            DeployApprovalType deployApprovalType = DeployApprovalType.getDeployApprovalType(workFlowNode.getApprovalType());
            switch (deployApprovalType){
                case AllApproval:{
                    checkAllAssignerApproval(flowContext);
                }break;
                case AnyApproval:{
                    completeTaskOption.setNextNode = true;
                }break;
                case SequentialApproval:{
                    checkAllAssignerApproval(flowContext);
                }break;
            }
        }
    }

    @Override
    public String name() {
        return "设置工作流审批节点是否已经审批完成";
    }

    private void checkAllAssignerApproval(FlowContext flowContext){
        WorkFlowInstance workFlowInstance = flowContext.checkInstanceData(WorkFlowInstance.class);
        WorkFlowNode workFlowNode = flowContext.checkInstanceData(WorkFlowNode.class);
        CompleteTaskOption completeTaskOption = flowContext.checkInstanceData(CompleteTaskOption.class);
        CompleteTaskRequest completeTaskRequest = flowContext.getInstanceData(CompleteTaskRequest.class);

        //判断已完成任务个数
        Condition condition = null;
        if(flowContext.containInstanceKey(Transaction.class)){
            Transaction transaction = flowContext.checkInstanceData(Transaction.class);
            transaction.commit();
            condition = transaction.query(WorkFlowTask.class);
        }else{
            DAO dao = flowContext.checkInstanceData(DAO.class);
            condition = dao.query(WorkFlowTask.class);
        }

        //查询node
        List<WorkFlowTask> completeTaskList = condition
                .addQuery("instanceId", workFlowInstance.getId())
                .addQuery("nodeId", workFlowNode.getId())
                .addColumn("id")
                .addColumn("complete")
                .execute()
                .getList();
        if(null==completeTaskList||completeTaskList.isEmpty()){
            completeTaskOption.setNextNode = true;
            flowContext.brokenCurrentFlow("任务列表为空");
        }
        if(null!=completeTaskRequest){
            WorkFlowTask completeTask = QueryInstanceList.newQuery(completeTaskList)
                    .addQuery("id", completeTaskRequest.taskId)
                    .execute()
                    .getOne();
            if(null!=completeTask){
                completeTask.setComplete(true);
            }
        }

        int countOfComplete = 0;
        for(WorkFlowTask currentCompleteTask:completeTaskList){
            if(null!=currentCompleteTask&&currentCompleteTask.isComplete()){
                countOfComplete++;
            }
        }

        int countOfAssigner = workFlowNode.getAssigner().size();

        if(countOfComplete==countOfAssigner){
            completeTaskOption.setNextNode = true;
        }
    }

}